﻿using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace UniFrame.Scene
{
    /// <summary>
    /// 场景状态控制机
    /// </summary>
    public class SceneController
    {
        /// <summary>
        /// 标记当前场景是否已经加载
        /// </summary>
        public bool sceneIsLoaded { get; private set; }
        /// <summary>
        /// 场景状态控制机
        /// </summary>
        public SceneController()
        {
            PreviousScene = null;
            CurrentScene = null;
            sceneIsLoaded = false;
        }
        /// <summary>
        /// 上一个场景
        /// </summary>
        public BaseScene PreviousScene { get; private set; }
        /// <summary>
        /// 当前场景
        /// </summary>
        public BaseScene CurrentScene { get; private set; }
        /// <summary>
        /// 设置当前场景
        /// </summary>
        /// <param name="scene"></param>
        public void SetState(BaseScene scene)
        {
            if (scene == null)
                return;
            sceneIsLoaded = false;
            if (CurrentScene != null)
                PreviousScene = CurrentScene;
            CurrentScene = scene; 
            if (SceneManager.GetActiveScene().name != scene.SceneName)
                SceneManager.LoadScene(scene.SceneName);
        }
        /// <summary>
        /// 异步加载场景
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public IEnumerator SetStateAsync(BaseScene scene, Action<float> func = null)
        {
            if (scene == null)
                yield break;
            sceneIsLoaded = false;
            if (CurrentScene != null)
                PreviousScene = CurrentScene;           
            CurrentScene = scene;
            
            if (SceneManager.GetActiveScene().name != scene.SceneName)
            {
                AsyncOperation op = SceneManager.LoadSceneAsync(scene.SceneName);
                op.allowSceneActivation = false;
                while (!op.isDone)
                {
                    if (op.progress < 0.9f)
                        func?.Invoke(op.progress);
                    else
                    {
                        // do something for wait ……
                        func?.Invoke(1.0f);
                        op.allowSceneActivation = true;
                    }
                    yield return null;
                }
            }
            else
                func(1.0f);
            
        }
        /// <summary>
        /// 场景逻辑更新
        /// </summary>
        public void Update()
        {
            if (CurrentScene == null)
                return;
            if (!SceneManager.GetSceneByName(CurrentScene.SceneName).isLoaded)
            {
                if (PreviousScene != null)
                    PreviousScene.OnSceneUpdate();
                return;
            }
            if (!sceneIsLoaded)
            {              
                if (PreviousScene != null)
                {
                    PreviousScene.OnSceneExit();
                    PreviousScene.Release();
                }
                sceneIsLoaded = true;
                CurrentScene.Initialize();
                CurrentScene.OnSceneEnter();          
            }
            else
                CurrentScene.OnSceneUpdate();
        }
    }
}
